package com.duobaoyu.dby.supply.biz.client.resource.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.duobaoyu.dby.common.core.constant.SecurityConstants;
import com.duobaoyu.dby.common.core.constant.ServiceNameConstants;
import com.duobaoyu.dby.common.core.constant.StringPool;
import com.duobaoyu.dby.common.core.util.R;
import com.duobaoyu.dby.resource.admin.feign.RemoteResourceBizConfigAdminService;
import com.duobaoyu.dby.resource.common.admin.dto.config.BizConfigDTO;
import com.duobaoyu.dby.resource.common.admin.dto.config.BizConfigQueryDTO;
import com.duobaoyu.dby.resource.common.admin.to.config.BizConfigInfoTO;
import com.duobaoyu.dby.resource.remote.common.json.PlatformServiceMappingInfoJson;
import com.duobaoyu.dby.resource.remote.common.to.config.BizConfigTO;
import com.duobaoyu.dby.supply.biz.client.resource.ResourceBusinessConfigAdminClient;
import com.duobaoyu.dby.supply.biz.client.resource.bean.bo.BusinessConfigBO;
import com.duobaoyu.dby.supply.biz.client.resource.bean.dto.BusinessConfigDTO;
import com.duobaoyu.dby.supply.biz.client.resource.bean.dto.BusinessConfigQueryDTO;
import com.duobaoyu.dby.supply.biz.client.resource.bean.vo.BusinessConfigInfoVO;
import com.duobaoyu.dby.supply.biz.client.resource.bean.vo.BusinessConfigVO;
import com.duobaoyu.dby.supply.biz.client.resource.converter.ResourceConverter;
import com.duobaoyu.dby.supply.biz.enums.LocalCacheKeys;
import com.duobaoyu.dby.supply.biz.util.RemoteResultCheckUtil;
import com.duobaoyu.dby.supply.core.cache.service.LocalCacheService;
import com.duobaoyu.dby.supply.core.common.exception.CustomAssert;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author liyang
 * @version 1.0.0
 * @ClassName ResourceBusinessConfigAdminClientImpl
 * @createTime 12:16:00 2023/10/08
 */
@Component
@RequiredArgsConstructor
public class ResourceBusinessConfigAdminClientImpl implements ResourceBusinessConfigAdminClient {

    private final LocalCacheService localCacheService;
    private final ResourceConverter resourceConverter;
    private final RemoteResourceBizConfigAdminService remoteResourceBizConfigAdminService;

    @Override
    public Boolean removeConfigIds(List<Long> configIds) {
        R<Boolean> result = remoteResourceBizConfigAdminService.batchDeleteByIds(configIds, SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, configIds);
        return result.getData();
    }

    @Override
    public Boolean deleteCache() {
        R<Boolean> result = remoteResourceBizConfigAdminService.deleteCache(SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, StringPool.EMPTY);
        return result.getData();
    }

    @Override
    public Boolean saveBusinessConfig(BusinessConfigDTO businessConfig) {
        BizConfigDTO dto = resourceConverter.toBizConfig(businessConfig);
        R<Boolean> result = remoteResourceBizConfigAdminService.save(dto, SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, businessConfig);
        return result.getData();
    }

    @Override
    public Page<BusinessConfigInfoVO> queryPage(BusinessConfigQueryDTO businessConfigQuery) {
        BizConfigQueryDTO dto = resourceConverter.toBizConfigQuery(businessConfigQuery);
        R<Page<BizConfigInfoTO>> result = remoteResourceBizConfigAdminService.queryPage(dto, SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, businessConfigQuery);
        return resourceConverter.toBusinessConfigPage(result.getData());
    }

    @Override
    public BusinessConfigInfoVO details(Long id) {
        R<BizConfigInfoTO> result = remoteResourceBizConfigAdminService.details(id, SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, id);
        return resourceConverter.toBusinessConfig(result.getData());
    }

    @Override
    public List<BusinessConfigVO> getProductMappingBizConfig() {
        List<BusinessConfigBO> businessConfigList = getCacheBizCode().stream().filter(BusinessConfigBO::getSaasProductMapping).collect(Collectors.toList());
        return resourceConverter.toBusinessConfigList(businessConfigList);
    }

    @Override
    public List<BusinessConfigVO> getBizConfig() {
        List<BusinessConfigBO> businessConfigList = this.getCacheBizCode();
        return resourceConverter.toBusinessConfigList(businessConfigList);
    }

    @Override
    public BusinessConfigVO getBizCode(String bizCode) {
        String localCacheKey = LocalCacheKeys.BIZ_CODE.formatKey(bizCode);
        BusinessConfigBO cache = (BusinessConfigBO) localCacheService.getCache(localCacheKey);
        if(Objects.isNull(cache)){
            synchronized (this) {
                cache = (BusinessConfigBO) localCacheService.getCache(localCacheKey);
                if(Objects.isNull(cache)){
                    List<BusinessConfigBO> items = this.getCacheBizCode();
                    CustomAssert.isTrue(CollectionUtils.isNotEmpty(items),"biz code not configured");
                    Map<String, BusinessConfigBO> bizConfigMap = items.stream().collect(Collectors.toMap(item -> LocalCacheKeys.BIZ_CODE.formatKey(item.getBizCode()), item -> item));
                    localCacheService.putAllCache(bizConfigMap);
                    cache = bizConfigMap.get(localCacheKey);
                }
            }
        }
        return resourceConverter.toBusinessConfig(cache);
    }

    private List<BusinessConfigBO> getCacheBizCode() {
        R<List<BizConfigTO>> result = remoteResourceBizConfigAdminService.getCache(SecurityConstants.FROM_IN);
        RemoteResultCheckUtil.checkRemoteResult(result, ServiceNameConstants.RESOURCE_SERVICE, StringPool.EMPTY);
        List<BusinessConfigBO> configs = Lists.newArrayList();
        for(BizConfigTO to : result.getData()){
            List<Long> platformServiceIds = Lists.newArrayList();
            if(CollectionUtils.isNotEmpty(to.getPlatformServiceMappingInfo())){
                platformServiceIds = to.getPlatformServiceMappingInfo().stream().map(PlatformServiceMappingInfoJson::getPlatformServiceId).collect(Collectors.toList());
            }
            configs.add(BusinessConfigBO.builder().bizCode(to.getBizCode()).bizDescribe(to.getBizDescribe())
                    .bizCustom(to.getBizCustom()).saasProductMapping(to.getSaasProductMapping()).orderSnPrefix(to.getOrderSnPrefix())
                    .platformServiceIds(platformServiceIds).build());
        }
        return configs;
    }
}
